<script lang="ts" setup>
import { ref, reactive, computed, watch, onMounted } from 'vue';
import { Message } from '@arco-design/web-vue';
import API from '@/services';
import { store } from '@/store';
import { IconClose, IconDown } from '@arco-design/web-vue/es/icon';

const emit = defineEmits(['updateItem']);
const {
  boardLable: { postBoardLabel, getBoardLabelList, deleteBoardLabelById },
  board: { putPublishById },
  publicBoardDir: { getBoardDirTree },
  userInfoService: { getUser, getUserRoles }
} = API;
const props = withDefaults(
  defineProps<{
    title: string;
    showDesc?: boolean;
  }>(),
  {
    title: '',
    showDesc: false
  }
);
const releaseVisible = ref(false);
const releaseForm = reactive({
  desc: '',
  pathId: '',
  labels: '',
  permission: 1,
  visibleRole: <any>[],
  visibleUser: <any>[],
  auths: <any>[]
});
const releaseFormRef = ref();
const permissionOption = [
  {
    value: 1,
    label: '公开'
  },
  {
    value: 2,
    label: '指定用户可见'
  }
];
const labelOptions = ref<any>([]);
const checkboxIdList = ref<any>([]);
const labelName = ref('');
const labelNameRef = ref();
const cardId = ref(-1); // 当前看板的id值
const treeList = ref<defs.PublicBoardDirTreeNodeVO[]>();
const treeListProcess = ref<defs.PublicBoardDirTreeNodeVO[]>(); // 用来存放处理后的树 因为看板只能放在3级目录下
const authorizeRoleList = computed(
  () => store.state.indextree.authorizeRoleList
);
const authorizeUserList = computed(
  () => store.state.indextree.authorizeUserList
);
const cardItem = ref();

// 获取存放的目录id
const getPathId = (id: any) => {
  releaseForm.pathId = id;
};

// 获取角色
const getAuthorizeRoleList = async () => {
  try {
    const { code, data }: any = await getUserRoles({});
    if (code === 200) {
      store.commit('indextree/changeAuthorizeRoleList', data);
    }
  } catch (error) {
    console.log(error);
  }
};

// 获取用户
const getAuthorizeUserList = async () => {
  try {
    const { code, data }: any = await getUser({});
    if (code === 200) {
      store.commit('indextree/changeAuthorizeUserList', data);
    }
  } catch (error) {
    console.log(error);
  }
};

// 显示弹窗
const showReleaseModal = (item: any, type?: string) => {
  let itemPublishCont: any = {};
  labelOptions.value = [];
  resetForm();
  getLabelList().then(() => {
    cardItem.value = item;
    cardId.value = item.id;
    releaseVisible.value = true;
    if (type === 'isEdit') {
      itemPublishCont = JSON.parse(item.publishJson);
      releaseForm.desc = item.description;
      releaseForm.pathId = itemPublishCont.boardDirId;
      releaseForm.labels = filterLabelIds(itemPublishCont.boardLabelIds);
      itemPublishCont.auths.forEach((item: any) => {
        if (item.authBodyType === 1) {
          releaseForm.permission = 1;
        } else {
          releaseForm.permission = 2;
          item.authBodyType === 2
            ? releaseForm.visibleRole.push(item.authBodyCode)
            : releaseForm.visibleUser.push(item.authBodyCode);
        }
      });
    }
  });
};

// 关闭弹窗之前
const onBeforeOk = async (done: any) => {
  const err = await releaseFormRef.value.validate();
  if (!err) {
    if (
      releaseForm.permission === 2 &&
      !releaseForm.visibleRole.length &&
      !releaseForm.visibleUser.length
    ) {
      Message.error('可见角色与可见用户需选择一项');
      done(false);
    } else {
      done(true);
    }
  } else {
    done(false);
  }
};

// 处理表单的权限配置参数(auth: { authBodyCode: string, authBodyType: number, authType: number })
const processAuth = () => {
  releaseForm.auths = [];
  if (releaseForm.permission === 1) {
    let obj = {
      authBodyCode: '',
      authBodyType: 1,
      authType: 1
    };
    releaseForm.auths.push(obj);
  } else {
    releaseForm.visibleRole?.forEach((item: any) => {
      let obj = {
        authBodyCode: item,
        authBodyType: 2,
        authType: 1
      };
      releaseForm.auths.push(obj);
    });
    releaseForm.visibleUser?.forEach((item: any) => {
      let obj = {
        authBodyCode: item,
        authBodyType: 3,
        authType: 1
      };
      releaseForm.auths.push(obj);
    });
  }
};

// 点击确定
const handleOk = async () => {
  processAuth();
  try {
    const { code, data } = await putPublishById(
      { id: cardId.value },
      {
        description: releaseForm.desc,
        auths: releaseForm.auths,
        boardDirId: releaseForm.pathId,
        boardLabelIds: checkboxIdList.value
      }
    );
    if (code === 200) {
      Message.success('发布成功');
      resetForm();
      emit('updateItem');
    }
  } catch (error) {
    console.log(error, '发布时候的错误');
  } finally {
    // releaseFormRef.value.resetFields();
    // releaseFormRef.value.clearValidate();
    releaseVisible.value = false;
  }
};

// 点击取消
const handleCancel = () => {
  releaseVisible.value = false;
  releaseFormRef.value.resetFields();
  releaseFormRef.value.clearValidate();
};

// 删除标签
const deleteLabel = async (id: number) => {
  try {
    const { code }: any = await deleteBoardLabelById({ id });
    if (code === 200) {
      checkboxIdList.value.forEach((item: any, index: number) => {
        if (item === id) {
          checkboxIdList.value.splice(index, 1);
        }
      });
      Message.success('删除成功');
      getCheckLabelList(checkboxIdList.value);
      let index = labelOptions.value.findIndex((item: any) => item.id === id);
      labelOptions.value.splice(index, 1);
    } else {
      Message.error('删除失败');
    }
  } catch (error) {
    console.log(error);
  }
};

// 添加标签
const addLabel = async () => {
  if (!labelName.value) {
    Message.error('标签名称不能为空');
    return;
  }
  try {
    const res = await postBoardLabel({ name: labelName.value });
    if (res.code === 200) {
      Message.success('新增成功');
      getLabelList();
      labelName.value = '';
    } else {
      Message.error(res.msg);
    }
  } catch (error) {
    console.log(error);
  }
};

// 获取选中的标签
const getCheckLabelList = (val: any) => {
  checkboxIdList.value = val;
};

// 获取标签列表
const getLabelList = async () => {
  try {
    const { code, data }: any = await getBoardLabelList({});
    if (code === 200) {
      labelOptions.value = data;
    }
  } catch (error) {
    console.log(error);
  }
};

// 过滤上前项的标签
const filterLabelIds = (list: any) => {
  let arr = list.filter((id: number) =>
    labelOptions.value.some((item: any) => id === item.id)
  );
  return arr;
};

// 获取树(用作存放目录)
const getTreeNodeList = async () => {
  try {
    const { code, data }: any = await getBoardDirTree({});
    if (code === 200) {
      const arr = [];
      data?.children.forEach((item: any) => {
        if (!item.parentId) {
          item.parentId = data.id;
        }
      });
      arr.push(data);
      treeList.value = arr;
      processTree(data);
      localStorage.setItem('treeListS', JSON.stringify(treeList.value));
    }
  } catch (error) {
    console.log(error);
  } finally {
  }
};

// 处理树的结果
const processTree = (data: defs.PublicBoardDirTreeNodeVO[]) => {
  data.forEach((item: any) => {
    if (item.level === 3) {
      delete item.children;
    } else {
      // 匹配不到就继续递归
      item.children && processTree(item.children);
    }
  });
  treeListProcess.value = data;
};

// 请求用户角色数据
const getAuthorizeList = () => {
  if (!authorizeRoleList.value || !authorizeRoleList.value.length) {
    getAuthorizeRoleList();
  }
  if (!authorizeUserList.value || !authorizeUserList.value.length) {
    getAuthorizeUserList();
  }
};

// 重置表单数据
const resetForm = () => {
  releaseForm.desc = '';
  releaseForm.pathId = '';
  releaseForm.labels = '';
  releaseForm.permission = 1;
  releaseForm.visibleRole = [];
  releaseForm.visibleUser = [];
  releaseForm.auths = [];
  checkboxIdList.value = [];
};

// 聚焦input
const focusInput = () => {
  labelNameRef.value.focus();
};

onMounted(() => {
  let treeListS: any = localStorage.getItem('treeListS');
  treeList.value = JSON.parse(treeListS);
  if (!treeList.value || !treeList.value.length) {
    getTreeNodeList();
  } else {
    processTree(treeList.value);
  }
});

defineExpose({ showReleaseModal });
</script>

<template>
  <a-modal
    v-model:visible="releaseVisible"
    :on-before-ok="onBeforeOk"
    @ok="handleOk"
    @cancel="handleCancel"
    @open="getAuthorizeList"
    modal-class="release-modal"
    unmountOnClose
    auto-label-width
    width="36%"
  >
    <template #title>
      <span style="font-weight: bold"> {{ props.title }}</span>
    </template>
    <div>
      <a-form
        :model="releaseForm"
        class="release-form"
        ref="releaseFormRef"
        :class="
          releaseForm.permission === 2
            ? 'release-form-item-more'
            : 'release-form-item-normal'
        "
      >
        <a-form-item
          v-if="props.showDesc"
          field="desc"
          label="描述"
          :rules="[{ required: true, message: '请输入描述' }]"
        >
          <a-textarea
            v-model="releaseForm.desc"
            placeholder="请输入"
            :max-length="200"
            allow-clear
            show-word-limit
            auto-size
            :style="{ height: '36px' }"
          />
        </a-form-item>
        <a-form-item
          field="pathId"
          label="存放目录"
          :rules="[{ required: true, message: '请选择存放的目录' }]"
        >
          <a-cascader
            :model-value="releaseForm.pathId"
            :options="treeListProcess"
            expand-trigger="click"
            allow-clear
            placeholder="请选择"
            @change="getPathId"
            :style="{ height: '36px' }"
            :field-names="{
              value: 'id',
              label: 'name',
              children: 'children'
            }"
          />
        </a-form-item>
        <a-form-item field="label" label="标签">
          <a-select
            v-model="releaseForm.labels"
            placeholder="请选择"
            multiple
            :options="labelOptions"
            :field-names="{ value: 'id', label: 'name' }"
            @change="getCheckLabelList"
            :style="{ minHeight: '36px' }"
          >
            <template #arrow-icon>
              <IconDown class="arco-select-arrow-icon" />
            </template>
            <template #option="{ data }">
              <div class="form-label-wrap">
                <span>{{ data.raw.name }}</span>
                <icon-close
                  class="check-delete"
                  :style="{ fontSize: '16px', color: '#B3B8C4' }"
                  @click.stop.prevent="deleteLabel(data.raw.id)"
                />
              </div>
            </template>
            <template #footer>
              <div class="add-label">
                <a-input
                  placeholder="请输入"
                  style="width: 83%; height: 30px"
                  v-model="labelName"
                  ref="labelNameRef"
                  @click="focusInput"
                >
                </a-input>
                <a-button type="text" @click="addLabel">添加标签</a-button>
              </div>
            </template>
            <template #empty>
              <div class="add-label">
                <a-input
                  placeholder="请输入"
                  style="width: 83%; height: 30px"
                  v-model="labelName"
                  ref="labelNameRef"
                  @click="focusInput"
                >
                </a-input>
                <a-button type="text" @click="addLabel">添加标签</a-button>
              </div>
            </template>
          </a-select>
        </a-form-item>
        <a-form-item field="permission" label="查看权限" required>
          <a-select
            :style="{ width: '130px', height: '36px' }"
            v-model="releaseForm.permission"
            @change="selectPermission"
          >
            <a-option
              v-for="item of permissionOption"
              :value="item.value"
              :label="item.label"
              :key="item.value"
            />
          </a-select>
        </a-form-item>
        <a-form-item
          v-show="releaseForm.permission === 2"
          field="visibleRole"
          label="可见角色"
        >
          <a-select
            v-model="releaseForm.visibleRole"
            placeholder="请选择"
            multiple
            :style="{ minHeight: '36px' }"
          >
            <template #arrow-icon>
              <IconDown class="arco-select-arrow-icon" />
            </template>
            <a-option
              v-for="item of authorizeRoleList"
              :value="item.value"
              :label="item.label"
              :key="item.value"
            />
          </a-select>
        </a-form-item>
        <a-form-item
          v-show="releaseForm.permission === 2"
          field="visibleUser"
          label="可见用户"
        >
          <a-select
            v-model="releaseForm.visibleUser"
            placeholder="请选择"
            multiple
            :style="{ minHeight: '36px' }"
          >
            <template #arrow-icon>
              <IconDown class="arco-select-arrow-icon" />
            </template>
            <a-option
              v-for="item of authorizeUserList"
              :value="item.value"
              :label="item.label"
              :key="item.value"
            />
          </a-select>
        </a-form-item>
      </a-form>
    </div>
  </a-modal>
</template>

<style lang="scss" scoped>
::v-deep(.arco-form-item-label-col) {
  width: 16%;
  text-align: right;
  flex: 0 0 16%;
}
::v-deep(.arco-form-item-wrapper-col) {
  flex: 0 0 84%;
  width: 84%;
}
.release-form-item-normal {
  padding-bottom: 240px;
}
.release-form-item-more {
  padding-bottom: 140px;
}
.form-label-wrap {
  width: 390px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  .check-delete {
    width: 16px;
    height: 16px;
    margin-left: auto;
    display: block;
  }
}
.add-label {
  padding: 10px 12px;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

<style lang="scss">
.release-modal {
  .arco-modal-body {
    padding: 18px;
    .arco-select-view-multiple .arco-select-view-tag {
      background-color: #f6f8fc;
      font-size: 12px;
      color: #33353b;
      padding: 2px 9px;
      border-radius: 4px;
    }
  }
}
.popper-label {
  margin: 0;
  padding: 0;
  .arco-popover-content {
    margin-top: 0;
  }
}
</style>
